package com.tedu.manager;

import com.tedu.element.map.GameMap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @说明 专门负责从.map文件加载地图数据的工具类
 * <p>此类与 ElementManager解耦，解析文件后返回一个 GameMap对象
 */
public class MapLoader {
    // 私有化构造函数，防止外部实例化
    private MapLoader() {}

    /**
     * 内部类，用于封装从地图文件加载的所有数据
     */
    public static class MapData {
        private final GameMap gameMap;
        private final Map<String, String> objectConfigs;

        public MapData(GameMap gameMap, Map<String, String> objectConfigs) {
            this.gameMap = gameMap;
            this.objectConfigs = objectConfigs;
        }

        public GameMap getGameMap() {
            return gameMap;
        }

        public Map<String, String> getObjectConfigs() {
            return objectConfigs;
        }
    }

    /**
     * @说明 加载指定 ID 的地图，并返回一个 MapData 实例
     * @param mapId 地图 ID
     * @return 加载成功返回一个 MapData 对象，失败返回 null
     */
    public static MapData loadMap(String mapId) {
        String mapPath = "com/tedu/text/" + mapId + ".map";
        ClassLoader classLoader = MapLoader.class.getClassLoader();

        try (InputStream is = classLoader.getResourceAsStream(mapPath)) {
            if (is == null) {
                System.err.println("地图文件不存在: " + mapPath);
                return null;
            }

            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            return parseMapFile(reader);
        } catch (Exception e) {
            System.err.println("解析地图文件时出错: " + mapPath);
            throw new RuntimeException();
        }
    }

    /**
     * @说明 解析地图文件流，并构建 GameMap对象。
     * @param reader 地图文件的 BufferedReader
     * @return 构建好的 MapData 对象
     * @throws IOException 文件格式错误
     */
    private static MapData parseMapFile(BufferedReader reader) throws IOException {
        // 解析地图网格
        // 第一行：地图尺寸 & 地板类型
        String line = reader.readLine();
        if (line == null || line.trim().isEmpty()) {
            throw new IOException("地图文件格式错误：第一行缺失。");
        }

        String[] dimensions = line.split(" ");
        if (dimensions.length != 3) {
            throw new IOException("地图文件格式错误：第一行需要包含宽度、高度和地板类型。");
        }
        int width = Integer.parseInt(dimensions[0]);
        int height = Integer.parseInt(dimensions[1]);
        int floorTileCode = Integer.parseInt(dimensions[2]);

        // 初始化地图
        GameMap gameMap = new GameMap(width, height, floorTileCode);

        // 读取地图数据行
        for (int y = 0; y < height; y++) {
            line = reader.readLine();
            if (line == null) {
                throw new IOException("地图文件格式错误：地图数据行数不足");
            }

            String[] tiles = line.split(" ");
            for (int x = 0; x < width && x < tiles.length; x++) {
                if (!tiles[x].isEmpty()) {
                    int tileCode = Integer.parseInt(tiles[x]);
                    gameMap.setTile(x, y, tileCode);
                }
            }
        }

        // 解析对象配置
        Map<String, String> objectConfigs = new HashMap<>();
        boolean inObjectSection = false;
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            if (line.equalsIgnoreCase("[objects]")) {
                inObjectSection = true;
                continue;
            }
            if (inObjectSection && !line.isEmpty() && !line.startsWith("#")) {
                String[] parts = line.split("=", 2);
                if (parts.length == 2) {
                    objectConfigs.put(parts[0].trim(), parts[1].trim());
                }
            }
        }

        return new MapData(gameMap, objectConfigs);
    }
}
